package com.h5ve.flow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.h5ve.base.exception.BaseException;
import com.h5ve.flow.mapper.WarmFlowMapper;
import com.h5ve.flow.service.ExecuteService;
import com.h5ve.flow.vo.FlowHisTaskVo;
import com.h5ve.flow.vo.FlowTaskVo;
import com.h5ve.security.util.SecurityUtil;
import com.h5ve.system.entity.User;
import org.dromara.warm.flow.core.constant.ExceptionCons;
import org.dromara.warm.flow.core.entity.HisTask;
import org.dromara.warm.flow.core.entity.Task;
import org.dromara.warm.flow.orm.entity.FlowHisTask;
import org.dromara.warm.flow.orm.entity.FlowInstance;
import org.dromara.warm.flow.orm.entity.FlowTask;
import org.dromara.warm.flow.orm.mapper.FlowHisTaskMapper;
import org.dromara.warm.flow.orm.mapper.FlowInstanceMapper;
import org.dromara.warm.flow.orm.mapper.FlowTaskMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author warm
 * @description: 流程执行serviceImpl
 * @date: 2023/5/29 13:09
 */
@Service
public class ExecuteServiceImpl implements ExecuteService {

    @Resource
    private WarmFlowMapper flowMapper;
    @Resource
    private FlowInstanceMapper flowInstanceMapper;
    @Resource
    private FlowTaskMapper flowTaskMapper;
    @Resource
    private FlowHisTaskMapper flowHisTaskMapper;

    @Override
    public Page<FlowTaskVo> toDoPage(Page<FlowTaskVo> page, Task task) {
        return page.setRecords(flowMapper.toDoPage(task));
    }

    @Override
    public Page<FlowHisTask> donePage(Page<FlowHisTask> page, HisTask hisTask) {
        return page.setRecords(flowMapper.donePage(hisTask));
    }

    @Override
    public Page<FlowHisTask> copyPage(Page<FlowHisTask> page, FlowTask flowTask) {
        return page.setRecords(flowMapper.copyPage(flowTask));
    }

    /**
     * 根据ID反显姓名
     *
     * @param ids 需要反显姓名的用户ID
     * @return {@link List <User>}
     * @author liangli
     * @date 2024/8/21 17:11
     **/
    @Override
    public List<User> idReverseDisplayName(Long[] ids) {
        if (Objects.isNull(ids) || ids.length == 0) {
            return null;
        }
        return flowMapper.idReverseDisplayName(ids);
    }

    @Override
    public List<FlowHisTaskVo> flowHisTasks(Long businessId) {
        FlowInstance flowInstance = flowInstanceMapper.selectOne(new LambdaQueryWrapper<FlowInstance>().eq(FlowInstance::getBusinessId, businessId));
        if (ObjectUtil.isNull(flowInstance)) {
            throw new BaseException(ExceptionCons.NOT_FOUNT_INSTANCE);
        }
        List<FlowHisTaskVo> list = new ArrayList<>();
        //历史任务
        LambdaQueryWrapper<FlowHisTask> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FlowHisTask::getInstanceId, flowInstance.getId());
        //wrapper.eq(FlowHisTask::getNodeType, NodeType.BETWEEN.getKey());
        wrapper.orderByDesc(FlowHisTask::getCreateTime).orderByAsc(FlowHisTask::getUpdateTime);
        List<FlowHisTask> flowHisTasks = flowHisTaskMapper.selectList(wrapper);
        if (CollUtil.isNotEmpty(flowHisTasks)) {
            list.addAll(BeanUtil.copyToList(flowHisTasks, FlowHisTaskVo.class));
        }
        //运行中的任务
        List<FlowTask> flowTaskList = flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class)
                .eq(FlowTask::getInstanceId, flowInstance.getId()));
        if (CollUtil.isNotEmpty(flowTaskList)) {
            List<FlowHisTaskVo> flowHisTaskVos = BeanUtil.copyToList(flowTaskList, FlowHisTaskVo.class);
            for (FlowHisTaskVo flowHisTaskVo : flowHisTaskVos) {
                flowHisTaskVo.setFlowStatus("");
                flowHisTaskVo.setUpdateTime(null);
                flowHisTaskVo.setRunDuration(null);
                /*List<UserDTO> allUser = flwTaskService.currentTaskAllUser(flowHisTaskVo.getId());
                if (CollUtil.isNotEmpty(allUser)) {
                    String join = StreamUtils.join(allUser, e -> String.valueOf(e.getUserId()));
                    flowHisTaskVo.setApprover(join);
                }*/
                if ("6".equals(flowInstance.getFlowStatus()) || "9".equals(flowInstance.getFlowStatus())) {
                    flowHisTaskVo.setApprover(SecurityUtil.getUser().getId().toString());
                    flowHisTaskVo.setApproveName(SecurityUtil.getUser().getNickName());
                }
            }
            list.addAll(flowHisTaskVos);
        }
        return list;
    }
}
